<template>
  <div>
    <!-- 控制按钮区域 -->
    <div class="control-buttons">
      <button @click="setDataType('precipitation')" :class="{ active: currentDataType === 'precipitation' }">降水量</button>
      <button @click="setDataType('temperature')" :class="{ active: currentDataType === 'temperature' }">温度</button>
      <button @click="setDataType('pressure')" :class="{ active: currentDataType === 'pressure' }">气压</button>
    </div>

    <!-- 时间轴区域 -->
    <div class="timeline">
      <input type="range" min="0" :max="timeSlots.length - 1" :value="selectedTimeSlot" v-model="selectedTimeSlot" @input="updateWeatherDataForSelectedTime" />
      <span>{{ formatTime(timeSlots[selectedTimeSlot]) }}</span>
    </div>

    <!-- 地图展示区域 -->
    <div ref="mapChart" class="map-container"></div>
  </div>
</template>

<script>
import * as echarts from 'echarts';
import 'echarts/extension/bmap/bmap';
import axios from 'axios';
import stationData from '@/data/stationData.json'; // 确保路径正确

export default {
  name: 'WeatherMap',
  data() {
    return {
      ak: 'GJ85UIFoOx1S4HMTbouE9q8ZFi9lU9xD', // 替换为你申请的百度地图 API Key
      isScriptLoaded: false, // 标记百度地图脚本是否已加载
      mapChartInstance: null, // ECharts 实例
      precipitationData: [], // 降水量数据
      temperatureData: [], // 温度数据
      pressureData: [], // 气压数据
      stationMap: {}, // 站点ID到站点信息的映射
      currentDataType: 'precipitation', // 当前显示的数据类型
      activeStationId: null, // 当前显示信息窗口的站点 ID
      timeSlots: [], // 存储时间轴的时间点
      selectedTimeSlot: 0, // 当前选中的时间点索引
      weatherDataByTime : {},
    };
  },
  mounted() {
    this.prepareStationMap();
    this.loadBaiduMap();
    this.fetchWeatherData();
  },
  methods: {

    formatTime(timeSlot) {
      const date = new Date(timeSlot);
      return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')} ${String(date.getHours()).padStart(2, '0')}:00`;
    },

    /**
     * 准备站点ID到站点信息的映射
     */
    prepareStationMap() {
      this.stationMap = {};
      stationData.forEach((station) => {
        this.stationMap[station['区站号']] = {
          name: station['站名'],
          longitude: parseFloat(station['经度']),
          latitude: parseFloat(station['纬度']),
        };
      });
    },

    /**
     * 获取最新时间点的气象数据（降水量、温度、气压）
     */
    async fetchWeatherData() {
      try {
        const response = await axios.get('http://localhost:8080/api/weather/national');
        if (response.data.code !== 0) {
          console.error('接口返回错误:', response.data.msg);
          return;
        }

        const weatherData = response.data.data.WeatherStationDataPrefab;
        const latestData = this.getLatestWeatherData(weatherData);

        this.timeSlots = this.getTimeSlots(weatherData);
        this.selectedTimeSlot = this.timeSlots.length - 1;  // 默认选择最后一个时间点

        // 为每个时间点存储天气数据
        this.weatherDataByTime = {};
        weatherData.forEach(item => {
          const date = new Date(item.Year, item.Mon - 1, item.Day, item.Hour).toISOString();
          if (!this.weatherDataByTime[date]) {
            this.weatherDataByTime[date] = [];
          }
          this.weatherDataByTime[date].push({
            stationId: item.Station_Id_C,
            precipitation: item.PRE_3h,
            temperature: item.TEM,
            pressure: item.PRS,
          });
        });

        this.updateWeatherDataForSelectedTime(); // 更新初始地图数据

      } catch (error) {
        console.error('无法获取气象数据:', error);
      }
    },

    updateWeatherDataForSelectedTime() {
      const selectedTime = this.timeSlots[this.selectedTimeSlot];
      const weatherDataForTime = this.weatherDataByTime[selectedTime] || [];

      // 分别存储降水量、温度和气压数据
      this.precipitationData = weatherDataForTime
          .filter(item => this.filterValidRainData(item.precipitation)) // 过滤有效降水数据
          .map((item) => ({
            name: this.stationMap[item.stationId].name,
            value: [
              this.stationMap[item.stationId].longitude,
              this.stationMap[item.stationId].latitude,
              item.precipitation,
            ],
          }));

      this.temperatureData = weatherDataForTime
          .filter(item => this.filterValidTemperatureData(item.temperature)) // 过滤有效温度数据
          .map((item) => ({
            name: this.stationMap[item.stationId].name,
            value: [
              this.stationMap[item.stationId].longitude,
              this.stationMap[item.stationId].latitude,
              item.temperature,
            ],
          }));

      this.pressureData = weatherDataForTime
          .filter(item => this.filterValidPressureData(item.pressure)) // 过滤有效气压数据
          .map((item) => ({
            name: this.stationMap[item.stationId].name,
            value: [
              this.stationMap[item.stationId].longitude,
              this.stationMap[item.stationId].latitude,
              item.pressure,
            ],
          }));

      this.updateMapData(); // 更新地图显示
    },


    /**
     * 更新地图数据和样式
     */
    updateMapData() {

      if (!this.mapChartInstance) return;

      const option = this.getMapOption();
      this.mapChartInstance.setOption(option, true);
    },

    getTimeSlots(weatherData) {
      const timeSlots = new Set();

      let minTime = null;
      let maxTime = null;

      weatherData.forEach((item) => {
        const date = new Date(item.Year, item.Mon - 1, item.Day, item.Hour);

        // 更新最小和最大时间
        if (!minTime || date < minTime) minTime = date;
        if (!maxTime || date > maxTime) maxTime = date;

        timeSlots.add(date.toISOString());
      });

      const sortedTimeSlots = Array.from(timeSlots).sort();

      // 计算时间间隔（例如每隔3小时显示一个时间点）
      const interval = 3 * 60 * 60 * 1000;  // 3小时
      const adjustedTimeSlots = [];
      for (let time = minTime; time <= maxTime; time = new Date(time.getTime() + interval)) {
        adjustedTimeSlots.push(time.toISOString());
      }

      return adjustedTimeSlots;
    },

    /**
     * 在地图上点击站点进行操作
     */
    onStationClick(params) {
      const stationName = params.name; // 获取站点名称
      const station = Object.values(this.stationMap).find(st => st.name === stationName);

      if (!station) {
        console.error('未找到对应站点:', stationName);
        return;
      }

      // 平移到站点，并更新地图中心
      this.centerMapOnStation(station.longitude, station.latitude);

      // 显示站点信息窗口并常驻显示
      this.showStationTooltip(params, station.longitude, station.latitude);

      // 设置当前活动站点 ID
      this.activeStationId = stationName;
    },

    /**
     * 在地图上定位到指定站点
     */
    centerMapOnStation(longitude, latitude, stationName) {
      const bmapComponent = this.mapChartInstance.getModel().getComponent('bmap');
      const map = bmapComponent.getBMap();

      // 创建目标点
      const point = new BMap.Point(longitude, latitude);

      // 平移地图到目标点
      map.panTo(point);
      map.setZoom(5); // 根据需要调整缩放级别

      // 显示站点信息提示框，并常驻显示
      this.mapChartInstance.dispatchAction({
        type: 'showTip',
        seriesIndex: 0,  // 假设天气数据在第一个 series 中
        name: stationName,  // 显示站点名称
      });

      // 添加全局点击事件监听器，点击其他地方时隐藏提示框
      map.addEventListener('click', () => {
        this.mapChartInstance.dispatchAction({
          type: 'hideTip',
        });
      });
    },

    /**
     * 显示站点信息提示框，点击站点后常驻显示
     */
    showStationTooltip(params, longitude, latitude) {
      // 触发显示提示框的 action
      this.mapChartInstance.dispatchAction({
        type: 'showTip',
        seriesIndex: 0,
        dataIndex: params.dataIndex, // 确保数据索引与站点匹配
        position: [longitude, latitude], // 固定显示在经纬度位置
      });

      // 添加事件监听，点击地图其他地方隐藏提示框
      const bmapComponent = this.mapChartInstance.getModel().getComponent('bmap');
      const map = bmapComponent.getBMap();

      map.addEventListener('click', () => {
        this.mapChartInstance.dispatchAction({
          type: 'hideTip',
        });
      });
    },

    /**
     * 获取每个站点最新的气象数据
     */
    getLatestWeatherData(weatherData) {
      const latestDataMap = {};

      weatherData.forEach((item) => {
        const stationId = item.Station_Id_C;
        const currentTime = new Date(item.Year, item.Mon - 1, item.Day, item.Hour);

        if (!latestDataMap[stationId] || currentTime > latestDataMap[stationId].time) {
          latestDataMap[stationId] = {
            stationId: stationId,
            precipitation: item.PRE_3h,
            temperature: item.TEM,
            pressure: item.PRS,
            time: currentTime,
          };
        }
      });

      // 转换为数组并过滤掉没有站点信息的
      return Object.values(latestDataMap).filter((item) => this.stationMap[item.stationId]);
    },

    /**
     * 过滤掉异常温度
     */
    filterValidTemperatureData(temperature) {
        return temperature < 100 && temperature > -100;
    },

    /**
     * 过滤掉异常气压
     */
    filterValidPressureData(pressure) {
        return pressure < 2000 && pressure > 100;
    },

    /**
     * 过滤掉异常降水
     */
    filterValidRainData(precipitation) {
        return precipitation < 100000;
    },

    /**
     * 动态加载百度地图 API 脚本
     */
    loadBaiduMap() {
      if (this.isScriptLoaded) {
        this.initializeEChartsMap();
        return;
      }

      const scriptExists = document.querySelector(`script[src="https://api.map.baidu.com/api?v=3.0&ak=${this.ak}"]`);
      if (scriptExists) {
        console.warn('百度地图脚本已存在');
        this.initializeEChartsMap();
        return;
      }

      const script = document.createElement('script');
      script.type = 'text/javascript';
      script.src = `https://api.map.baidu.com/api?v=3.0&ak=${this.ak}&callback=initBaiduMapCallback`;
      script.onerror = () => {
        console.error('百度地图脚本加载失败');
        alert('百度地图脚本加载失败，请检查网络连接和 API Key。');
      };

      window.initBaiduMapCallback = this.initializeEChartsMap;
      document.head.appendChild(script);
      this.isScriptLoaded = true;
    },

    /**
     * 初始化 ECharts 地图
     */
    initializeEChartsMap() {
      if (this.mapChartInstance) {
        this.mapChartInstance.resize();
        return;
      }

      this.mapChartInstance = echarts.init(this.$refs.mapChart);
      const option = this.getMapOption();
      this.mapChartInstance.setOption(option);

      // 监听窗口大小变化，自动调整图表大小
      window.addEventListener('resize', () => {
        if (this.mapChartInstance) {
          this.mapChartInstance.resize();
        }
      });

      // 添加点击事件监听
      this.mapChartInstance.on('click', this.onStationClick);
    },


    /**
     * 获取地图配置选项
     */
    getMapOption() {
      let dataToShow = [];
      let visualMapConfig = {};

      if (this.currentDataType === 'precipitation') {
        dataToShow = this.precipitationData;
        visualMapConfig = {
          min: 0,
          max: 20,
          splitNumber: 4,
          inRange: {
            color: ['#00FF00', '#FFFF00', '#FFA500', '#FF4500'], // 绿色到红色
          },
          text: ['高', '低'],
          calculable: true,
          left: 'left',
          bottom: '10%',
          formatter: '{value} mm',
        };
      } else if (this.currentDataType === 'temperature') {
        dataToShow = this.temperatureData;
        visualMapConfig = {
          min: -10,
          max: 40,
          splitNumber: 5,
          inRange: {
            color: ['#0000FF', '#00FFFF', '#FFFF00', '#FF7F00', '#FF0000'], // 蓝色到红色
          },
          text: ['高', '低'],
          calculable: true,
          left: 'left',
          bottom: '10%',
          formatter: '{value} °C',
        };
      } else if (this.currentDataType === 'pressure') {
        dataToShow = this.pressureData;
        visualMapConfig = {
          min: 900,
          max: 1050,
          splitNumber: 5,
          inRange: {
            color: ['#ADD8E6', '#87CEFA', '#4682B4', '#0000FF', '#00008B'], // 浅蓝到深蓝
          },
          text: ['高', '低'],
          calculable: true,
          left: 'left',
          bottom: '10%',
          formatter: '{value} hPa',
        };
      }

      return {
        title: {
          text: `全国主要城市气象数据 - ${this.getTitleText()}`,
          subtext: '数据来源：中国气象局',
          left: 'center',
        },
        tooltip: {
          trigger: 'item',
          formatter: (params) => {
            let unit = '';
            if (this.currentDataType === 'precipitation') {
              unit = ' mm';
            } else if (this.currentDataType === 'temperature') {
              unit = ' °C';
            } else if (this.currentDataType === 'pressure') {
              unit = ' hPa';
            }
            return `${params.name} : ${params.value[2]}${unit}`;
          },
        },
        visualMap: visualMapConfig,
        bmap: {
          center: [104.114129, 37.550339],
          zoom: 5.5,
          roam: false,
          mapStyle: {
            styleJson: [
              { featureType: 'water', elementType: 'all', stylers: { color: '#d1d1d1' } },
              { featureType: 'land', elementType: 'all', stylers: { color: '#f3f3f3' } },
              { featureType: 'railway', elementType: 'all', stylers: { visibility: 'off' } },
              { featureType: 'highway', elementType: 'all', stylers: { color: '#fdfdfd' } },
              { featureType: 'arterial', elementType: 'geometry', stylers: { color: '#fefefe' } },
              { featureType: 'poi', elementType: 'all', stylers: { visibility: 'off' } },
              { featureType: 'boundary', elementType: 'all', stylers: { color: '#fefefe' } },
            ],
          },
        },
        series: [
          {
            name: this.getTitleText(),
            type: 'scatter',
            coordinateSystem: 'bmap',
            data: dataToShow,
            symbolSize: (val) => this.getSymbolSize(val[2]),
            label: {
              formatter: '{b}',
              position: 'right',
              show: false,
            },
            emphasis: {
              label: {
                show: true,
              },
            },
            itemStyle: {
              shadowBlur: 10,
              shadowColor: '#333',
            },
          },
        ],
      };
    },

    /**
     * 获取地图标题文本
     */
    getTitleText() {
      if (this.currentDataType === 'precipitation') return '降水量';
      if (this.currentDataType === 'temperature') return '温度';
      if (this.currentDataType === 'pressure') return '气压';
      return '';
    },

    /**
     * 根据数据类型和数值获取符号大小
     */
    getSymbolSize(value) {
      if (this.currentDataType === 'precipitation') {
        return value === 0 ? 0 : Math.min(10 + value * 2, 40);
      } else if (this.currentDataType === 'temperature' || this.currentDataType === 'pressure') {
        return 20;
      }
      return 0;
    },

    /**
     * 设置当前数据类型并更新地图
     */
    setDataType(type) {
      if (['precipitation', 'temperature', 'pressure'].includes(type)) {
        this.currentDataType = type;
        this.updateMapData();
      }
    },
  },
};
</script>


<style scoped>
.map-container {
  width: 100vw;
  height: 100vh;
}

/* 控制按钮样式 */
.control-buttons {
  position: absolute;
  top: 20px;
  left: 20px;
  z-index: 1001;
  background: rgba(255, 255, 255, 0.8);
  padding: 10px;
  border-radius: 5px;
}

.control-buttons button {
  margin-right: 10px;
  padding: 5px 10px;
  border: none;
  background: #f0f0f0;
  cursor: pointer;
  border-radius: 3px;
}

.control-buttons button.active {
  background: #1890ff;
  color: white;
}

.control-buttons button:hover {
  background: #d9d9d9;
}
</style>
